from base_config import *
import re
import sys
import html

encrypt=[ ''.join([chr(j) for j in range(96,i)]) for i in range(96, 126) ][10:]

def get_tag_from_raw(content):

    current_entity = []
    batch = []
    def entity_to_batch(entity, line):
        if entity:
            batch.append(''.join(entity))
        if line:
            return [line + "\n"]
        else:
            return []

    for line in content.split('\n'):
        if char_is_label(line):
            if (current_entity and line[-3:] != current_entity[-1][-4:-1] ) or line.find("B-") > 0 :  #new class or a new start
                current_entity = entity_to_batch(current_entity, line)
            else: # I... after B
                current_entity.append(line + "\n")
        else:
            current_entity = entity_to_batch(current_entity, None)

    entity_to_batch(current_entity, None)

    return batch


def __remove_htmltag(content):
    return re.sub(r"< .*?> O\n", "",string=content, flags=re.S)

def __unescape_html(content):
    return html.unescape(content)


def parse_raw_out(content, remove_html = False):
    labeled = get_tag_from_raw(content)
    # print(labeled)
    c1, c2 = content + "\n",content + "\n"
    if remove_html:
        c2 = __remove_htmltag(c2)
    cat_bag = {}
    for tag in sorted(labeled, key = lambda  x:-len(x)):
        name = ''.join([x[0] for x in tag.strip().split("\n")])
        cat = tag[-4:-1]
        idsincat = cat_bag.setdefault(cat, set([]))
        repl = html_tag % (repl_map[cat], name)
        idsincat.add(repl)
        c1, c2 = (x.replace(tag, repl) for x in (c1, c2))
    c1, c2 = (re.sub("\sO\n", "", x) for x in (c1, c2))
    if remove_html :
        return c2
    return c1


def color_new_term(html_content, term, term_cat):
    if html_content.find(term) < 0:
        return html_content
    maybe_inside = re.findall('">[^>]*?{}[^<]*?</'.format(term) , html_content)

    avoid_replacements = [(k, encrypt[i]) for i,k in enumerate(maybe_inside)]
    for k, ii in avoid_replacements: #replace to encrypt
        html_content = re.sub(k, ii, html_content, 1)

    html_content = html_content.replace(term,  html_tag % (repl_map[term_cat], term))
    for k, ii in avoid_replacements: #replace encrypt back to
        html_content = re.sub(ii, k, html_content, 1)
    return html_content


def split_html(html_content):
    num = len(html_content)
    i = 0
    chars = []
    while i < num:
        if html_content[i:i+3] == '<fo':
            j = i+24
            while j < num:
                if html_content[j:j+3] == 'nt>':
                    elem = html_content[i:j+3]

                    kvs = re.findall('''((\w+)=['"]([^"']+)["'])''', elem)
                    text = re.findall(r'>(.*?)<', elem)[0]
                    info = dict([x[1:] for x in kvs])
                    info['text'] = text
                    chars.append(info)
                    break
                else:
                    j += 1
            i = j+3
        else:
            chars.append(html_content[i])
            i+=1
    return chars


def convert_back_ids_within(html_content, type_map, ids_off, endline = '\n'):
    '''with '\n' per char'''
    chars = split_html(html_content)
    result = []
    for c in chars:
        if type(c) == str:
            result.append("{}\tO{}".format(c, endline))
        else:
            text = c['text']
            char_types = [type_map[c['color']]] # LOC JOB
            if c.get('ids'):
                ids = [str(int(x) + ids_off) for x in  re.split(r"\D+", c.get('ids')) if x]
                char_types.append(','.join(ids))#ids
            type_tail = '-'.join(char_types)
            result.append("{}\tB-{}{}".format(text[0], type_tail, endline)) #B
            for cc in text[1:]:
                result.append("{}\tI-{}{}".format(cc, type_tail, endline))  # I
    return result


if __name__ == "__main__":
    # html_content = '北大清华图书馆、<font color="AF009F">北大清华图书馆</font>、<font color="AF009F">北图</font>、'
    # nt = color_new_term(html_content, "图", "JOB")
    bb = '''调查范围涉及<font color="0F3FAF" ids='id1-id2,3'>故宫</font>、'''
    nt = split_html(bb)
    print(convert_back_ids_within(bb, repl_map_revert, 1000))
